#include "stdafx.h"
#include "SRC.h"
#include"FileReader.h"

SRC SRC::instance;

SRC::SRC()
{
	isBranch = false;
}


SRC::~SRC()
{

}

bool SRC::Load()
{
	if (load_tmp.empty())
	{
		load_tmp.push(L"src/textures");
		if (isBranch)return false;
	}
	while (true)
	{
		auto path = load_tmp.front();
		load_tmp.pop();
		auto docs = FileReader::GetFileInFolder(path + L"/*");
		while (docs.size())
		{
			auto doc = docs.front();
			docs.pop();
			if (doc.IsFolder())
			{
				load_tmp.push(path + L"/" + doc.name);
				continue;
			}
			else
			{
				auto ex_n = doc.GetExtensionName();
				if (ex_n == L"jpg" || ex_n == L"jpeg" || ex_n == L"png" || ex_n == L"bmp")
					LoadTexture(path + L"/" + doc.name);
			}
		}
		if (load_tmp.empty())return true;
		if (isBranch)return false;
	}
}

void SRC::LoadTexture(std::wstring filename)
{
	textures.push_back(Tex(filename));
	path_to_tex[filename.substr(filename.find_first_of(L'/') + 1)] = textures.size() - 1;
}


void SRC::Release()
{
	for (auto & tex : textures)tex.ForceRelease();
	textures.clear();
	path_to_tex.clear();
}

int SRC::GetTexIdWithPath(std::wstring filename)
{
	if (path_to_tex.find(filename) == path_to_tex.end())return -1;
	return path_to_tex[filename];
}

SRC::Tex SRC::GetTexWithId(int id)
{
	if (!IsHaveTex(id))return Tex(L"");
	return textures[id];
}

bool SRC::IsHaveTex(int id)
{
	if (id < 0)return false;
	if (id >= textures.size())return false;
	return true;
}

SRC::Tex::Tex(std::wstring filename)
{
	if (filename.size() == 0)
	{
		img = nullptr;
		count = nullptr;
		return;
	}
	img = new CImage;
	img->Load(filename.c_str());
	count = new size_t;
	*count = 1;
	if (img->GetBPP() == 32)
	{
		int i; int j;
		for (i = 0; i < img->GetWidth(); i++)
		{
			for (j = 0; j < img->GetHeight(); j++)
			{
				byte *pByte = (byte *)img->GetPixelAddress(i, j);
				pByte[0] = pByte[0] * pByte[3] / 255;
				pByte[1] = pByte[1] * pByte[3] / 255;
				pByte[2] = pByte[2] * pByte[3] / 255;
			}
		}
	}
}

SRC::Tex::Tex(const Tex & tex)
{
	img = nullptr;
	count = nullptr;
	this->operator=(tex);
}

SRC::Tex::~Tex()
{
	Release();
}

SRC::Tex & SRC::Tex::operator=(const Tex & tex)
{
	this->Release();
	this->count = tex.count;
	++*this->count;
	this->img = tex.img;
	return *this;
}

bool SRC::Tex::IsValid()
{
	return count;
}

void SRC::Tex::Release()
{
	if (count == nullptr)return;
	--*count;
	if (*count == 0)
	{
		delete img;
		delete count;
	}
	count = nullptr;
	img = nullptr;
}

void SRC::Tex::ForceRelease()
{
	delete img;
	delete count;
	count = nullptr;
	img = nullptr;
}